<?php
/**
 * Created by PhpStorm.
 * Author: sitenv@aliyun.com
 * CreateTime: 2023/2/14 11:34
 * Blog：www.myblogs.xyz
 */

namespace App\Services;

use App\Constants\ResponseCode;
use Hyperf\Cache\Cache;

class ApiServices
{
    protected static $require = [];
    protected static $selectable = [];
    protected static $data = [];
    protected static $validate = [];
    protected static $userId = [];
    protected static $userData = [];
    protected static $error = '';
    protected static $code = '';

    public static function requireParam($param = [])
    {
        self::$require = $param;
    }

    public static function selectableParam($param = [])
    {
        self::$selectable = $param;
    }

    public static function verifyParam($request, $param = [])
    {
        if ($request->isMethod('post')){
            $requestData = $request->post();
        }else{
            $requestData = $request->all();
        }
        if (empty($requestData)){
            self::$error = '请求错误';
            self::$code = ResponseCode::PARAM_ERR;
            return false;
        }
        if (!empty($param)){
            self::$require = $param;
        }
        if (!empty(self::$require)){
            if (is_string(self::$require)){
                self::$require = explode(',', self::$require);
            }
        }
        if (!empty(self::$selectable)){
            if (is_string(self::$selectable)){
                self::$selectable = explode(',', self::$selectable);
            }
        }
        if (!empty(self::$require) || !empty(self::$selectable)){
            $param = array_merge(self::$require, self::$selectable);
            $arrayKeys = array_keys($requestData);
            foreach ($arrayKeys as $key) {
                if (!in_array($key, $param)){
                    unset($requestData[$key]);
                }
            }
            if (!empty(self::$require)){
                foreach (self::$require as $val){
                    if (!isset($requestData[$val]) || $requestData[$val] === ''){
                        if (!empty(self::$validate[$val])){
                            self::$error = self::$validate[$val];
                        }else{
                            self::$error = '缺少请求参数：' . $val;
                        }
                        self::$code = ResponseCode::PARAM_ERR;
                        return false;
                    }
                }
            }
            self::$data = $requestData;
        }
        return true;
    }

    protected function verifyToken($request, $require = true)
    {
        $auth_token = $request->header('Authorization');
        if (empty($auth_token)){
            if ($require){
                self::$error = '缺少请求头Authorization';
                self::$code = ResponseCode::UNAUTH;
                return false;
            }
        }
        $user_token = new UserToken();
        $result = $user_token->tokenAuth(md5($auth_token));
        if (empty($result->user_id)){
            if ($require){
                self::$error = '系统检测到您长时间未登陆，请重新登录';
                self::$code = ResponseCode::UNAUTH;
                return false;
            }
        }else{
            // 获取用户信息
            $user_model = new User();
            $user_fields = 'id,phone,openid,invite_id,status,third_check';
            $user_data = $user_model->getFind($result->user_id, $user_fields);
            if (empty($user_data)){
                if ($require) {
                    self::$error = '系统检测到您长时间未登陆，请重新登录';
                    self::$code = ResponseCode::UNAUTH;
                    return false;
                }
            }else{
                self::$data['user_id'] = $user_data->id;
                self::$userId = $user_data->id;
                self::$userData = $user_data;
            }
        }
        return true;
    }

    protected function verifyRequest($user_id = 0, int $timeout = 5)
    {
        if (!$user_id){
            $user_id = self::$userId;
        }
        $limit_key = 'limit_request_'.$user_id;
        $ip = $_SERVER['HTTP_ALI_CDN_REAL_IP'];
        $limit_ip_key = 'limit_ip_'.$ip;
        $limit_account_key = 'limit_account_'.$user_id;
        $cache = new Cache();
        $limit = $cache->get($limit_key);
        $limit_ip = $cache->get($limit_ip_key);
        $limit_account= $cache->get($limit_account_key);
        if($limit_account > 10){
            self::$error = '操作频繁，请稍后再试';
            self::$code = ResponseCode::FORBIDDEN;
            return false;
        }
        if($limit_account) {
            $cache->set($limit_account_key, $limit_account + 1, $timeout);
        }else {
            $cache->set($limit_account_key,1, $timeout);
        }
        if($limit){
            self::$error = '操作频繁，请稍后再试';
            self::$code = ResponseCode::FORBIDDEN;
            return false;
        }else {
            $cache->set($limit_key, $ip, $timeout);
        }
        if($limit_ip){
            self::$error = '操作频繁，请稍后再试';
            self::$code = ResponseCode::FORBIDDEN;
            return false;
        }else{
            $cache->set($limit_ip_key, $user_id, $timeout);
        }
        return true;
    }

    public static function getData()
    {
        return self::$data;
    }

    public static function verifyError()
    {
        return self::jsonError(self::$error);
    }


    /**
     * 附加参数
     * @param int $code
     * @param array $data
     * @param string $msg
     */
    private static function jsonReturn($code = 0, $data = [], $msg = '')
    {
        $result = [
            'msg'  => $msg,
            'code' => $code,
            'data' => $data,
        ];
        return $result;
    }

    /**
     * 请求验证失败
     * code 9999：请求验证失败
     * @param string $msg
     * @param array $data
     */
    public static function jsonFail($msg = '', $data = [])
    {
        return self::jsonReturn(ResponseCode::FORBIDDEN, (object)$data, $msg);
    }

    /**
     * 操作数据成功
     * code 1000：操作数据成功；可能有数据返回对象形式
     * @param string $msg
     * @param array $data
     */
    public static function jsonSuccess($msg = '', $data = [])
    {
        return self::jsonReturn(ResponseCode::SUCCESS, (object)$data, $msg);
    }

    /**
     * 操作数据失败
     * code 1001：操作数据失败
     * @param string $msg
     * @param array $data
     */
    public static function jsonError($msg = '', $data = [])
    {
        return self::jsonReturn(ResponseCode::PARAM_ERR, (object)$data, $msg);
    }

    /**
     * 获取数据成功
     * code 1000：获取数据成功；肯定有数据返回对象数组形式
     * @param array $data
     * @param string $msg
     */
    public static function jsonResult($data = [], $msg = '')
    {
        return self::jsonReturn(ResponseCode::SUCCESS, $data, $msg);
    }

    /**
     * 没有更多数据
     * code 1001：没有更多数据；空对象数组数据
     * @param array $data
     * @param string $msg
     */
    public static function jsonEmpty($msg = '', $data = [])
    {
        return self::jsonReturn(ResponseCode::SUCCESS, $data, $msg);
    }

    /**
     * TOKEN失效
     * code 1002：TOKEN失效
     * @param array $data
     * @param string $msg
     */
    public static function jsonTokenFailed($msg = '', $data = [])
    {
        return self::jsonReturn(ResponseCode::UNAUTH, $data, $msg);
    }
}